package cn.com.callback

import cn.com.elite.EliteBean
import cn.com.elite.Util
import cn.com.kh.KHDBConfig
import cn.com.kh.KHUtil
import net.sf.json.JSONObject
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.jdbc.core.JdbcTemplate

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 *
 * @Title: 项目Token相关统一管理接口* @author: LJT*
 *
 */

public class apiGetToken implements ServiceBackInvoke {
    private static final Log log = LogFactory.getLog(apiGetToken.class);

    public String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) {

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");

        // 调用IP过滤
        if (KHDBConfig.getParam(eliteBean, "#APIIP") == "1" && !KHUtil.getRemoteHost(request)) {
            log.warn("API被非法IP调用-Request Not Allow!");
            return "Request Not Allow!";
        }

        // 获取数据源List<Map<String, Object>>
        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource());

        String getMethod = request.getMethod();
        log.debug("getMethod:" + getMethod);

        JSONObject result = new JSONObject();
        JSONObject datatoken = new JSONObject();

        String APP_ID = "";

        if (getMethod.equals("GET")) {
            APP_ID = request.getParameter("appid");
            log.debug("原始Get请求参数:" + APP_ID);
        } else {
            InputStreamReader reader = new InputStreamReader(request.getInputStream(), "UTF-8");
            BufferedReader iny = new BufferedReader(reader);
            String line;
            while ((line = iny.readLine()) != null) {
                APP_ID += line;
            }
            log.debug("原始Post请求参数:" + APP_ID);
        }

        //  入参为空
        if (KHUtil.isNull(APP_ID)) {
            log.debug("APP_ID入参为空-无法完成操作!");
            result.put("code", -2);
            result.put("msg", "APP_ID入参为空-无法完成操作!");

            return result.toString();
        }

        try {
            // 检查当前Token状态
            String selectSQL = "select token, expired from kh_accesstoken where app_id = ? and del_flag = 0 and date_add(createdtime,interval expired second) > now() limit 1";
            List<Map<String, Object>> selectExits = jt.queryForList(selectSQL, APP_ID);
            if (selectExits.size() > 0) {
                Map selectExitsm = selectExits.get(0);
                String TOKEN = selectExitsm.get("token");
                Long EXPIRED = Long.parseLong(selectExitsm.get("expired").toString());

                result.put("code", 1);
                result.put("msg", "查询完成");
                datatoken.put("access_token", TOKEN);
                datatoken.put("expires_in", EXPIRED);
                result.put("data", datatoken);

            } else {
                Map<String, String> tokenMap = new HashMap<>();
                /* 企业微信
                WXG开头 企业微信
                WXM开头 微信小程序
                WXA开头 微信公众号

                */

                if (APP_ID == "FAX") {
                    tokenMap = getFAXToken(eliteBean);
                } else if (APP_ID == "SMS") {
                    tokenMap = getPAToken(eliteBean, APP_ID);
                } else if (APP_ID.indexOf("WXG") == 0) {
                    tokenMap = getWXToken(eliteBean, APP_ID);
                } else if (APP_ID.indexOf("WXM") == 0) {
                    tokenMap = getWXMToken(eliteBean, APP_ID);
                } else if (APP_ID.indexOf("WXA") == 0) {
                    tokenMap = getWXToken(eliteBean, APP_ID);
                } else {
                    log.warn("获取Token类型不支持");
                    result.put("code", -2);
                    result.put("msg", "获取Token类型不支持");
                    result.put("data", datatoken);
                    return result.toString();
                }

                String TOKEN = tokenMap.get("access_token");
                Long EXPIRED = Long.parseLong(tokenMap.get("expires_in").toString());

                dealToDB(jt, APP_ID, TOKEN, EXPIRED);

                result.put("code", 1);
                result.put("msg", "更新完成");
                datatoken.put("access_token", TOKEN);
                datatoken.put("expires_in", EXPIRED);
                result.put("data", datatoken);

            }

        } catch (Exception e) {
            log.error("接口处理异常", e);
            // 失败返回

            result.put("code", -1);
            result.put("msg", e.getMessage());
            result.put("data", datatoken);

        }

        log.debug("Token处理完成返回结果:" + result.toString());

        return result.toString();
    }

    // 将Token更新到DB
    public static void dealToDB(JdbcTemplate jt, String APP_ID, String access_token, Long expires_in) {

        // 清理超长时间的Token
        String dealSQL = "Delete From KH_Accesstoken Where Createdtime < Date_Add(Now(), Interval - 1 Day) And APP_ID = ?";
        jt.update(dealSQL, APP_ID);

        // 标识近期内Token无效
        dealSQL = "Update KH_Accesstoken Set Del_Flag = 1 Where Del_Flag = 0 And APP_ID = ?";
        jt.update(dealSQL, APP_ID);

        // 将新获取的Token入库存储
        dealSQL = "Insert Into Kh_Accesstoken (Rec_Id, Token, Createdtime, Expired, Del_Flag, APP_ID) Values (UUID(), ?, Now(), ?, 0, ?)";
        jt.update(dealSQL, access_token, expires_in, APP_ID);
    }

    // 获取企微&微信公众号Token
    public static Map<String, String> getWXToken(EliteBean eliteBean, String APP_ID) {

        Map<String, String> tokenMap = new HashMap<String, String>();

        // 调用微信获取最新Token
        String wxTokenURL = KHDBConfig.getAPIURL(eliteBean, "APIToken-" + APP_ID);

        log.debug("调用API获取最新TokenURL:" + wxTokenURL);

        String wxTokenResult = Util.doHttpGet(wxTokenURL, "UTF-8", 5000, 0);
        log.debug("调用API获取最新Token返回：" + wxTokenResult);
        JSONObject wxTokenJson = JSONObject.fromObject(wxTokenResult);

        int code = wxTokenJson.getInt("errcode");

        if (code == 0) {
            try {

                String access_token = wxTokenJson.getString("access_token");
                String expires_in = wxTokenJson.getString("expires_in");
                tokenMap.put("access_token", access_token);
                tokenMap.put("expires_in", expires_in);

            } catch (Exception e) {
                log.error(e);
            }
        }

        return tokenMap;
    }

    // 获取微信小程序Token
    public static Map<String, String> getWXMToken(EliteBean eliteBean, String APP_ID) {

        Map<String, String> tokenMap = new HashMap<String, String>();

        // 调用微信获取最新Token
        String wxTokenURL = KHDBConfig.getAPIURL(eliteBean, "APIToken-" + APP_ID);

        log.debug("调用API获取最新TokenURL:" + wxTokenURL);

        String wxTokenResult = Util.doHttpGet(wxTokenURL, "UTF-8", 5000, 0);
        log.debug("调用API获取最新Token返回：" + wxTokenResult);
        JSONObject wxTokenJson = JSONObject.fromObject(wxTokenResult);

        try {

            String access_token = wxTokenJson.getString("access_token");
            String expires_in = wxTokenJson.getString("expires_in");
            tokenMap.put("access_token", access_token);
            tokenMap.put("expires_in", expires_in);

        } catch (Exception e) {
            log.error(e);
        }


        return tokenMap;
    }

    // 获取水务传真接口Token
    public static Map<String, String> getFAXToken(EliteBean eliteBean) {

        Map<String, String> tokenMap = new HashMap<String, String>();

        Map<String, String> headParams = new HashMap<String, String>();
        headParams.put("Content-Type", "application/x-www-form-urlencoded");

        Map<String, String> callParams = new HashMap<String, String>();
        callParams.put("username", KHDBConfig.getParam(eliteBean, "FAXUSR"));
        callParams.put("password", KHDBConfig.getParam(eliteBean, "FAXPWD"));

        String callBody = KHUtil.urlencode(callParams, "");
        String tokenResult = Util.doHttpPostUseHead(KHDBConfig.getAPIURL(eliteBean, "FAX-loginURL"), callBody, "UTF-8", 120000, 0, headParams);
        log.debug("传真-获取接口Token【tokenResult】:" + tokenResult);

        JSONObject tokenJson = JSONObject.fromObject(tokenResult);
        int code = tokenJson.getInt("code");

        if (code == 0) {
            String access_token = tokenJson.getJSONObject("data").getString("token");
            tokenMap.put("access_token", access_token);
            tokenMap.put("expires_in", "7200");
        }
        log.debug("传真-获取接口Token【access_token】:" + tokenMap.toString());
        return tokenMap;
    }

    // 获取平安短信Token
    public static Map<String, String> getPAToken(EliteBean eliteBean, String APP_ID) {

        Map<String, String> tokenMap = new HashMap<String, String>();

        try {
            // 处理头文件
            Map<String, String> headerMap = new HashMap<String, String>();
            headerMap.put("Accept", "application/json");
            headerMap.put("Content-Type", "application/json");

            // Body
            JSONObject postBody = new JSONObject();
            postBody.put("grant_type", KHDBConfig.getParam(eliteBean, "SMS-GT"));
            postBody.put("client_id", KHDBConfig.getParam(eliteBean, "SMS-CI"));
            postBody.put("client_secret", KHDBConfig.getParam(eliteBean, "SMS-CS"));

            String postResult = Util.doHttpPostUseHead(KHDBConfig.getAPIURL(eliteBean, "PA-SMS-oauthUrl"), postBody.toString(), "UTF-8", 120000, 0, headerMap);
            System.out.println("返回请求体：" + postResult);

            JSONObject resultJson = JSONObject.fromObject(postResult);

            if (resultJson.getString("ret") == "0") {
                try {

                    String access_token = resultJson.getJSONObject("data").getString("access_token");
                    String expires_in = resultJson.getJSONObject("data").getString("expires_in");
                    tokenMap.put("access_token", access_token);
                    tokenMap.put("expires_in", expires_in);

                } catch (Exception e) {
                    log.error("当前解析Token接口返回结果异常-:" + e.getMessage());
                }
            }
        } catch (Exception e) {
            log.error("当前调用Token接口异常-:" + e.getMessage());
        }

        return tokenMap;
    }

}
